package cn.tianya.irock.bll;

import java.awt.image.BufferedImage;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import cn.tianya.irock.cache.AppCache;
import cn.tianya.irock.core.Configuration;
import cn.tianya.irock.core.DateTime;
import cn.tianya.irock.core.fileupload.disk.HttpPostedFile;
import cn.tianya.irock.data.dalfactory.DataAccess;
import cn.tianya.irock.data.idal.IAttachmentDataProvider;
import cn.tianya.irock.data.model.Attachment;
import cn.tianya.irock.data.model.Post;
import cn.tianya.irock.data.model.Site;
import cn.tianya.irock.data.model.SiteSettings;
import cn.tianya.irock.data.model.User;
import cn.tianya.irock.enums.PostFileResult;
import cn.tianya.irock.util.ImageUtils;
import cn.tianya.irock.util.MD5;


public class Attachments {
	
	private static IAttachmentDataProvider provider;
	private static Logger logger = Logger.getLogger(Attachments.class);
	public static String GROUP_ATTAS = "GROUP_ATTAS_U:{0}";
	public static String KEY_ATTAS = "atts:u:{0}_s:{1}_p:{2}";
	public static String KEY_ATTAS_TIME = "atts:u:{0}_s:{1}_t:{2}";
	
    static {
        provider = DataAccess.createAttachmentDataProvider();
    }
    
	public static PostFileResult addAttachment(Site site, User user, List<HttpPostedFile> files, String attDesc) {
		PostFileResult result = PostFileResult.Fail;
		SiteSettings settings = SiteManager.getCurrentSite().getSettings();
		for (HttpPostedFile file : files) {
			if (!settings.enableAttachments()) {
				
			} else if ((file.getSize() > settings.getMaxAttachmentSize() * 1024) && 
					settings.getMaxAttachmentSize() > 0 ) {
				result = PostFileResult.OutOfSize;
			} else if (!validateAttachmentType(file.getExtension())) {
				result = PostFileResult.UnAllowFileType;
			} else {
				Configuration cfg = Configuration.config();
				Attachment atta = new Attachment();
				atta.setSize(file.getSize());
				atta.setDescription(attDesc);
				atta.setContentType(file.getContentType());
				atta.setCreated(DateTime.now().getDate());
				
				String realName = stripPath(file.getName());

				atta.setFilename(realName);
				atta.setExtension(file.getExtension());
				atta.setFullPathname(Attachments.getFullPathFilename(site, atta));
				String savePath = cfg.getAppPath() + atta.getFullPathname();
				addAttachment(site, user, atta);
				file.saveAs(savePath);
				result = PostFileResult.Success;
			}
		}
		String group_key = MessageFormat.format(GROUP_ATTAS, user.getUserId());
		AppCache.clear(group_key);

		return result;
	}
	
	public static void addAttachment(Site site, User user, Attachment atta) {
		provider.add(site, user, atta);
	}
	
	public static List<Attachment> addSiteRes(Site site, List<HttpPostedFile> files) {
		return addSiteRes(site, files, false);
	}
	
	public static List<Attachment> addSiteRes(Site site, List<HttpPostedFile> files, boolean autoName) {
		String savePath = null;
		String name = null;
		Configuration cfg = Configuration.config();
		ArrayList<Attachment> attas = new ArrayList<Attachment>();
		Attachment att =null;
		
		for (HttpPostedFile file : files) {
			if(validateAttachmentType(file.getExtension())) {
				name = Attachments.getSiteResFullPathFilename(site, file, autoName);				
				
				savePath = cfg.getAppPath() + name;
				file.saveAs(savePath);
				
				att = new Attachment();
				att.setFullPathname(name);
				att.setFilename(file.getName());
				attas.add(att);
			}
		}
		return attas;
	}
	
	private static String stripPath(String realName) {
		String separator = "/";
		int index = realName.lastIndexOf(separator);
		
		if (index == -1) {
			separator = "\\";
			index = realName.lastIndexOf(separator);
		}
		
		if (index > -1) {
			realName = realName.substring(index + 1);
		}
		
		return realName;
	}
		
	private static String getSiteResFullPathFilename(Site site, HttpPostedFile file, boolean autoName) {
		Configuration cfg = Configuration.config();
		StringBuffer dir = new StringBuffer(256);
		String name = null;
		boolean success = false;
		
		dir.append(cfg.getResPath()).append('/').append(site.getName()).append('/');
		File siteDir = new File(cfg.getAppPath() + dir.toString());
		success = siteDir.exists();
		if (!success) {
			success = siteDir.mkdirs();
		}
		
		if (autoName) {
			String filename = MD5.crypt(file.getName() + System.currentTimeMillis()) + "." + file.getExtension();
			name = dir.append(filename).toString();
		} else {
			name = dir.append(file.getName()).toString();
		}
		return name;
	}
	
	private static String getFullPathFilename(Site site, String filename, String extension) {
		Configuration cfg = Configuration.config();
		Calendar c = new GregorianCalendar();
		c.setTimeInMillis(System.currentTimeMillis());
		c.get(Calendar.YEAR);
		
		int year = Calendar.getInstance().get(Calendar.YEAR);
		int month = Calendar.getInstance().get(Calendar.MONTH) + 1;
		//int day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
		boolean success = false;
		
		StringBuffer dir = new StringBuffer(256);
		dir.append(cfg.getResPath()).append('/')
		.append(site.getName()).append('/')
		.append(cfg.getUploadPath()).append("/")
		.append(year).append('/').append(month).append('/');
		
		File updir = new File(cfg.getAppPath() + dir.toString());
		success = updir.exists();
		if (!success) {
			success = updir.mkdirs();
		}
		
		return dir
			.append(MD5.crypt(filename + System.currentTimeMillis()))
			.append('_')
			.append(Users.getUser().getUserId())
			.append('.')
			.append(extension)
			.append('_')
			.toString();
	}
		
	private static String getFullPathFilename(Site site, Attachment att) {
		return getFullPathFilename(site, att.getFilename(), att.getExtension());
	}
	
	private static boolean validateAttachmentType(String rawExtension) {
		String[] types = SiteManager.getCurrentSite().getSettings().getAllowedAttachmentTypes().split(";");
		
		rawExtension = rawExtension.toLowerCase();
		for(String type : types) {
            if(type.trim().toLowerCase().equals(rawExtension)) {
                return true;
            }
        }
        return false;
	}
	
	private void createMaskImage(Site site, String path) {
		BufferedImage srcImg = null;
		BufferedImage maskImg = null;
		SiteSettings settings = null;
		String maskPath = null;
		StringBuilder dir = null;
		Configuration cfg = null;
		
		settings = SiteManager.getCurrentSite().getSettings();
		cfg = Configuration.config();
		dir = new StringBuilder(256);
		dir.append(cfg.getAppPath()).append(cfg.getResPath()).append('/').append(site.getName()).append('/').append(settings.getMaskImage());
		maskPath = dir.toString();
		try {
			srcImg = ImageUtils.getRAWImage(path);
			maskImg = ImageUtils.getRAWImage(maskPath);
			ImageUtils.createMaskImage(srcImg, maskImg);
			
			ImageUtils.saveImage(srcImg, path + "_mask", ImageUtils.IMAGE_JPEG);  
		}
		catch (Exception ex) {
			logger.error("Exception", ex);
		}
	}
	
	private void createThumb(String path) {
		SiteSettings settings = SiteManager.getCurrentSite().getSettings();
		
		try {
			BufferedImage image = ImageUtils.resizeImage(path, ImageUtils.IMAGE_JPEG, 
														settings.getImageThumbWidth(),
														settings.getImageThumbHeight());
			ImageUtils.saveImage(image, path + "_thumb", ImageUtils.IMAGE_JPEG);
		}
		catch (Exception ex) {
			logger.error("Exception", ex);
		}
	}
		
	public static List<Attachment> getAttachments(User user, Site site, Post post) {
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public static List<Attachment> getAttachments(User user, Site site, DateTime time) {
		String key = null;
		String group_key = null;
		List<Attachment> atts = null;
		
		key = MessageFormat.format(KEY_ATTAS_TIME, user.getUserId(), site.getSiteId(), time.toString("yyyy-MM-dd"));
		group_key = MessageFormat.format(GROUP_ATTAS, user.getUserId());
		atts = (List<Attachment>)AppCache.get(key);
		if (atts == null) {
			atts = provider.getAttachments(user,  site, time);
			AppCache.add(key, group_key, atts);
		}
		return atts;
	}
	
	public static List<Attachment> getAttachments(List<Integer> attids) {
		return provider.getAttachments(attids);
	}
		
	public static void delete(User owner, List<Integer> attids) {
		List<Attachment> attas = null;
		Configuration cofing = null;
		File file = null;
		String path = null;
		String group_key = null;
		
		attas = getAttachments(attids);
		cofing = Configuration.config();
		for (Attachment atta:attas) {
			path = cofing.getAppPath() + atta.getFullPathname();
			file = new File(path);   
			file.delete();
		}
		provider.delete(attids);
		group_key = MessageFormat.format(GROUP_ATTAS, owner.getUserId());
		AppCache.clear(group_key);
	}
}
